//
// Created by black on 2024/7/16.
//

#ifndef TDTRPROCESS_OBSERVER_H
#define TDTRPROCESS_OBSERVER_H

#include <mutex>
#include <set>
#include "Ordered.h"

template<class E, class V>
class Observer {
protected:
    std::mutex _mutex;
    std::set<E*, decltype(Ordered::compareOrderable)*> lstnrs = std::set<E*, decltype(Ordered::compareOrderable)*>(Ordered::compareOrderable);

    virtual void notifyValueToListener(E* listener, const V& value) const = 0;

    void notifyValue(const V& value) {
        std::lock_guard<std::mutex> l(_mutex);
        for (auto listener :  lstnrs) {
            notifyValueToListener(listener, value);
        }
    }

public:
    virtual ~Observer() = default;

    bool addListener(E* listener) {
        std::lock_guard<std::mutex> l(_mutex);
        if(!listener) return false;
        return lstnrs.insert(listener).second;
    }

    bool removeListener(E* listener) {
        std::lock_guard<std::mutex> l(_mutex);
        if(!listener) return false;
        return lstnrs.erase(listener);
    }

    virtual void put(V&& value) = 0;

    virtual void put(const V& value) = 0;
};


#endif //TDTRPROCESS_OBSERVER_H
